import java.util.Arrays;
import java.util.Comparator;
import java.util.TreeSet;

// 这是一个名为Code03_Comparator的类
public class Code03_Comparator {

    // 内部类Employee，表示员工类，包含公司编号和年龄两个属性
    public static class Employee {
        public int company;
        public int age;

        // 员工类的构造函数，用于初始化公司编号和年龄
        public Employee(int c, int a) {
            company = c;
            age = a;
        }
    }

    // 内部类EmployeeComparator实现了Comparator接口，用于定义Employee对象的比较规则
    public static class EmployeeComparator implements Comparator<Employee> {

        // 重写compare方法，比较规则为根据员工年龄比较
        // 如果o1的年龄小于o2的年龄，返回负数，表示o1的优先级更高（按照年龄从小到大排序）
        // 如果o1的年龄大于o2的年龄，返回正数，表示o2的优先级更高
        // 如果年龄相等，返回0
        @Override
        public int compare(Employee o1, Employee o2) {
            return o1.age - o2.age;
        }
    }

    public static void main(String[] args) {
        // 创建多个Employee对象
        Employee s1 = new Employee(2, 27);
        Employee s2 = new Employee(1, 60);
        Employee s3 = new Employee(4, 19);
        Employee s31 = new Employee(4, 19);
        Employee s4 = new Employee(3, 23);
        Employee s5 = new Employee(1, 35);
        Employee s6 = new Employee(3, 55);
        Employee[] arr = {s1, s2, s3, s4, s5, s6};

        // 使用自定义的比较器EmployeeComparator对数组进行排序
        Arrays.sort(arr, new EmployeeComparator());
        // 遍历排序后的数组并输出每个员工的公司编号和年龄
        for (Employee e : arr) {
            System.out.println(e.company + ", " + e.age);
        }

        System.out.println("=====");

        // 使用lambda表达式定义比较规则，按照年龄从大到小排序
        Arrays.sort(arr, (a, b) -> b.age - a.age);
        for (Employee e : arr) {
            System.out.println(e.company + ", " + e.age);
        }

        System.out.println("=====");

        // 使用lambda表达式定义比较规则，先按照公司编号从小到大排序，如果公司编号相同再按照年龄从小到大排序
        Arrays.sort(arr, (a, b) -> a.company!= b.company? (a.company - b.company) : (a.age - b.age));
        for (Employee e : arr) {
            System.out.println(e.company + ", " + e.age);
        }

        // 创建一个TreeSet，使用EmployeeComparator作为比较器
        TreeSet<Employee> treeSet1 = new TreeSet<>(new EmployeeComparator());
        for (Employee e : arr) {
            treeSet1.add(e);
        }
        // 输出TreeSet的大小，由于TreeSet不允许重复元素，这里会是6
        System.out.println(treeSet1.size());

        // 尝试添加一个已经存在的Employee对象（根据比较器的定义，年龄相同即为相同元素），TreeSet会去重
        treeSet1.add(new Employee(2, 27));
        // 输出TreeSet的大小，仍然为6
        System.out.println(treeSet1.size());

        System.out.println("===");

        // 创建一个新的TreeSet，使用更复杂的比较规则
        // 先按照公司编号比较，如果相同再按照年龄比较，如果年龄也相同则按照对象的toString方法比较（这里可以用来区分不同对象）
        TreeSet<Employee> treeSet2 = new TreeSet<>((a, b) -> a.company!= b.company? (a.company - b.company)
                : a.age!= b.age? (a.age - b.age) : a.toString().compareTo(b.toString()));
        for (Employee e : arr) {
            treeSet2.add(e);
        }
        // 输出TreeSet的大小，由于比较规则更细致，这里会是6
        System.out.println(treeSet2.size());

        // 尝试添加一个已经存在的Employee对象（根据前面的比较规则，这个对象与之前的不同），TreeSet不会去重
        treeSet2.add(new Employee(2, 27));
        // 输出TreeSet的大小，现在为7
        System.out.println(treeSet2.size());

        System.out.println("===");


        // 简单演示字符串的字典序比较
        String str1 = "abcde";
        String str2 = "ks";
        // 比较str1和str2，按照字典序，如果str1小于str2，返回负数
        System.out.println(str1.compareTo(str2));
        // 比较str2和str1，按照字典序，如果str2大于str1，返回正数
        System.out.println(str2.compareTo(str1));
    }
}